package com.zz.controller;

import com.zz.common.Log;
import com.zz.common.R;
import com.zz.entity.*;
import com.zz.service.*;

import com.zz.utils.AesEncryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import javax.validation.executable.ValidateOnExecution;
import java.util.List;
import java.util.Map;

/**
 * @author HUAWEI
 */
@RestController
@RequestMapping("/user")
@Slf4j
@CrossOrigin
@Validated
public class UserController {

    @Autowired
    private UserService userService;

    @Log(title = "用户登录",dataLocationType = "link", isUser = false)
    @PostMapping("/login")
    public R<String> login(@Length(min = 1, message = "用户名最少有一位") @RequestParam String name,
                           @Length(min = 8, message = "密码长度至少为8位") @RequestParam String password,
                           @RequestParam(defaultValue = "false") boolean rememberMe, HttpSession session) {
        // 解密
        name = AesEncryptUtils.decrypt(name);
        password = AesEncryptUtils.decrypt(password);
        //1 获取Subject对象
        Subject subject = SecurityUtils.getSubject();
        //2 封装请求数据到token对象中
        AuthenticationToken token = new UsernamePasswordToken(name, password, rememberMe);
        //3 调用login方法进行登录认证
        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            e.printStackTrace();
            return R.error("登录失败！用户名密码错误！");
        }

        //调用接口方法获取用户的角色信息
        List<String> roles = userService.getUserRoleInfo(name);
        //调用接口方法获取用户角色的权限信息
        List<String> permissions = userService.getUserPermissionInfo(roles);

        session.setAttribute("user", token.getPrincipal().toString());
        //登录后直接返回sessionId（也就是我们的token）给前端，当然你也可以通过其他方式给前端提供token
        //除了获取session，我们还可以通过subject.getPrincipal()获取我们的登录用户信息
        //return R.success("登陆成功！  token为："+subject.getSession().getId()+"   该用户权限路径为："+permissions);
        return R.success("登录成功！").add("token",subject.getSession().getId()).add("permissionPath",permissions);
    }

    //登录认证验证rememberMe
    @GetMapping("/userLoginRm")
    public String userLogin(HttpSession session) {
        session.setAttribute("user", "rememberMe");
        return "rememberMe！";
    }



    /**
    * 注册,使用了AES加密
     *接口测试成功
     *朱彦燕
    * */
    @PostMapping("/register")
    @Log(title = "用户注册", dataLocationType = "body", isUser = false)
    public R<String> register(@RequestBody @Valid User user){
        return userService.register(user);
    }

    /**
    *退出登录
    * 朱彦燕
    * 接口测试成功
     */
    @PostMapping("/logout")
    @Log(title = "用户退出登录", dataLocationType = "link", isUser = false)
    public R<String> logout(HttpServletRequest request){
        request.getSession().removeAttribute("user");
        return R.success("退出登录！");
    }

    /**
    * 忘记/重置密码,AES数据加密,手机验证码功能暂未实现
    * 朱彦燕
    * 测试成功
    * */
    @PostMapping("/reset")
    @Log(title = "用户重置密码", dataLocationType = "body", isUser = false)
    public R<String> resetPassword(@RequestBody @Valid Map<String, String> map){
        return userService.resetPassword(map);
    }
}
